package bjfu.it.sun.graduationproject.voicechat;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;

import android.Manifest;
import android.annotation.SuppressLint;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.media.AudioManager;
import android.media.MediaPlayer;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.provider.Settings;
import android.util.Log;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.ListView;
import android.widget.Toast;

import com.rabbitmq.client.BuiltinExchangeType;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
import com.rabbitmq.client.DeliverCallback;

import org.apache.commons.lang3.SerializationUtils;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import java.util.concurrent.TimeoutException;

import bjfu.it.sun.graduationproject.R;

public class ChatActivity extends AppCompatActivity {

    public static final int LOCATION_PERMISSION_REQUEST_CODE = 99;
    private static final String TAG = "MainActivity";
    AudioRecordButton sendmessagebutton;

    Button selectactivitybutton;
    Button increasevolumebutton;
    Button decreasevolumebutton;
    Button increasesizebutton;
    Button decreasesizebutton;
    Button deletebutton;
    int j;
    int i = 34;
    private ConnectionFactory factory;
    private Location mLastKnownLocation;

    private String mDir;

    private List<VoiceMessage> mDatas = new ArrayList();
    private ArrayAdapter<VoiceMessage> mAdapter;
    private ListView mListView;

    @SuppressLint({"MissingInflatedId", "MissingPermission"})
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_chat);
        //        获取控件
        sendmessagebutton = findViewById(R.id.sendmessage_nc);

        selectactivitybutton = findViewById(R.id.selectactivity_nc);
        increasevolumebutton = findViewById(R.id.increasevolume_nc);
        decreasevolumebutton = findViewById(R.id.decreasevolume_nc);
        increasesizebutton = findViewById(R.id.increasesize_nc);
        decreasesizebutton = findViewById(R.id.decreasesize_nc);


        mAdapter = new RecorderAdapter(this, mDatas);

        mListView = findViewById(R.id.recorder_list);
        mListView.setAdapter(mAdapter);
        mListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                Log.d(TAG, "播放" + mDatas.get(position).voiceFilePath);
//播放音频
                MediaManager.playSound(mDatas.get(position).voiceFilePath, new MediaPlayer.OnCompletionListener() {
                    @Override
                    public void onCompletion(MediaPlayer mp) {
                        Toast.makeText(getApplicationContext(), "播放完毕", Toast.LENGTH_SHORT).show();
                    }
                });
            }
        });


        mDir = this.getExternalCacheDir() + "/chatapp/recorder/audios";//最好判断SD卡是否存在可读

        // Register the listener with the Location Manager to receive location updates
        checkPermission();
        LocationManager locationManager = (LocationManager) this.getSystemService(Context.LOCATION_SERVICE);
        // Define a listener that responds to location updates
        LocationListener locationListener = new LocationListener() {
            public void onLocationChanged(Location location) {
                mLastKnownLocation = location;
            }

            public void onStatusChanged(String provider, int status, Bundle extras) {
            }

            public void onProviderEnabled(String provider) {
            }

            public void onProviderDisabled(String provider) {
            }
        };
        locationManager
                .requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 1000, 10, locationListener);
        locationManager
                .requestLocationUpdates(LocationManager.GPS_PROVIDER, 1000, 10, locationListener);

        // 获得AudioManager对象实例
        android.media.AudioManager am = (android.media.AudioManager) getSystemService(Context.AUDIO_SERVICE);
        // 获取手机当前音量值
        j = am.getStreamVolume(android.media.AudioManager.STREAM_VOICE_CALL);

        //连接设置
        setupConnectionFactory();

        //用于从线程中获取数据，更新ui
        final Handler incomingMessageHandler = new Handler() {
            @Override
            public void handleMessage(Message msg) {
                byte[] data = msg.getData().getByteArray("data");
                VoiceMessage voiceMessage = SerializationUtils.deserialize(data);

                if (null != voiceMessage && null != voiceMessage.latitude) {
                    float[] results = new float[1];
                    Location.distanceBetween(mLastKnownLocation.getLatitude(), mLastKnownLocation.getLongitude(), voiceMessage.latitude, voiceMessage.longitude, results);
                    voiceMessage.distance = results[0];
                }
                Log.i(TAG, "msg:" + voiceMessage.messageId);
                //这里是Voice的数据， 需要保存下来做播放


                try {
                    File dir = new File(mDir);//创建文件夹
                    if (!dir.exists()) {
                        dir.mkdirs();
                    }
                    String fileName = UUID.randomUUID().toString() + ".amr";//随机生成文件名
                    File file = new File(dir, fileName);//创建文件
                    if (!file.exists()) {
                        file.createNewFile();
                    }
                    FileOutputStream fos = new FileOutputStream(file);
                    fos.write(voiceMessage.voice);
                    fos.close();

                    voiceMessage.voiceFilePath = file.getAbsolutePath();
                    mDatas.add(voiceMessage);
                    mAdapter.notifyDataSetChanged();
                    Log.i(TAG, "path:" + file.getAbsolutePath());
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        };

        //开启消费者线程
        //subscribe(incomingMessageHandler);
        new Thread(new Runnable() {
            @Override
            public void run() {
                msgConsumer(incomingMessageHandler);
            }
        }).start();

//        发送消息点击事件
//        sendmessagebutton.setOnClickListener(new View.OnClickListener() {
//            @Override
//            public void onClick(View view) {
////                Intent intent=new Intent();
////                intent.setClass(MainActivity.this,VoiceInputActivity.class);
////                startActivity(intent);
//                new Thread(new Runnable() {
//                    @Override
//                    public void run() {
//                        msgProducer("我发送了一个消息！");
//                    }
//                }).start();
//
//
//            }
//        });

        sendmessagebutton.setAudioFinishRecorderListener(new AudioRecordButton.AudioFinishRecorderListener() {
            @Override
            public void onFinish(float seconds, String filePath) {
                Log.d(TAG, seconds + " " + filePath);
                new Thread(new Runnable() {
                    @Override
                    public void run() {
                        msgProducer(seconds, filePath);
                    }
                }).start();
            }
        });
//        选择活动点击事件
        selectactivitybutton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Intent intent1 = new Intent();
                intent1.setClass(ChatActivity.this, bjfu.it.sun.graduationproject.activitytag.SelectActivity.class);
                startActivity(intent1);
            }
        });
//        增大音量
        increasevolumebutton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                // 获取手机最大音量值
                int maxVolume = am.getStreamMaxVolume(android.media.AudioManager.STREAM_MUSIC);
                if (j >= maxVolume) {
                    Toast.makeText(ChatActivity.this, "当前音量值已经最大", Toast.LENGTH_SHORT).show();
                } else {
                    j = j + 1;
                    am.setStreamVolume(android.media.AudioManager.STREAM_MUSIC, j, 0);
                    Toast.makeText(ChatActivity.this, "当前音量值:" + j, Toast.LENGTH_SHORT).show();
                }
            }
        });

//        减小音量
        decreasevolumebutton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                if (j <= 0) {
                    Toast.makeText(ChatActivity.this, "当前音量值已经最小", Toast.LENGTH_SHORT).show();
                } else {
                    j = j - 1;
                    am.setStreamVolume(AudioManager.STREAM_MUSIC, j, 0);
                    Toast.makeText(ChatActivity.this, "当前音量值:" + j, Toast.LENGTH_SHORT).show();
                }
            }
        });

//        增大字体
        increasesizebutton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                if (i >= 50) {
                    Toast.makeText(ChatActivity.this, "字号已最大", Toast.LENGTH_SHORT).show();
                } else {
                    i = i + 10;
                    selectactivitybutton.setTextSize(i);
                    sendmessagebutton.setTextSize(i);

                }
            }
        });

//        减小字体
        decreasesizebutton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                if (i <= 10) {
                    Toast.makeText(ChatActivity.this, "字号已最小", Toast.LENGTH_SHORT).show();
                } else {
                    i = i - 10;
                    selectactivitybutton.setTextSize(i);
                    sendmessagebutton.setTextSize(i);

                }
            }
        });
    }

    /**
     * 连接设置
     */
    private void setupConnectionFactory() {
        factory = new ConnectionFactory();
        factory.setHost("101.42.174.162");
        factory.setPort(5672);
        factory.setUsername("guest");
        factory.setPassword("guest");
        factory.setVirtualHost("/");
    }

    /**
     * 收消息（从发布者那边订阅消息）
     */
    private void msgConsumer(final Handler handler) {

        try {
            //连接
            Connection connection = factory.newConnection();
            //通道
            final Channel channel = connection.createChannel();

            channel.exchangeDeclare("fanout.exchange", BuiltinExchangeType.FANOUT);
            String queueName = channel.queueDeclare().getQueue();
            channel.queueBind(queueName, "fanout.exchange", "");
            System.out.println(" [*] Waiting for messages. To exit press CTRL+C");

            DeliverCallback deliverCallback = (consumerTag, delivery) -> {
                byte[] data = delivery.getBody();
                Message uimsg = handler.obtainMessage();
                Bundle bundle = new Bundle();
                bundle.putByteArray("data", data);
                uimsg.setData(bundle);
                handler.sendMessage(uimsg);
            };
            channel.basicConsume(queueName, true, deliverCallback, consumerTag -> {
            });

        } catch (IOException e) {
            e.printStackTrace();
        } catch (TimeoutException e) {
            e.printStackTrace();
        }
    }

    /**
     * 发布者发布消息
     */
    private void msgProducer(float seconds, String filePath) {

        try {
            VoiceMessage voiceMessage = new VoiceMessage();
            voiceMessage.messageId = UUID.randomUUID().toString();
            voiceMessage.duration = seconds;
            // 发布消息
            if (null != mLastKnownLocation) {
                voiceMessage.latitude = mLastKnownLocation.getLatitude();
                voiceMessage.longitude = mLastKnownLocation.getLongitude();
            }
            //这里是Voice的数据
            if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
                byte[] body = Files.readAllBytes(Paths.get(filePath));
                voiceMessage.voice = body;
            }

            byte[] data = SerializationUtils.serialize(voiceMessage);

            //连接
            Connection connection = factory.newConnection();
            //创建消息通道
            Channel channel = connection.createChannel();
            // 声明exchange中的消息为可持久化，不自动删除
            channel.exchangeDeclare("fanout.exchange", BuiltinExchangeType.FANOUT, false, false, null);
//            // 发布消息
//            if (null != mLastKnownLocation) {
//                String locationStr = "Location:" + mLastKnownLocation.getLatitude() + " " + mLastKnownLocation.getLongitude();
//                message += locationStr;
//            }
            channel.basicPublish("fanout.exchange", "", null, data);
            channel.close();
            connection.close();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (TimeoutException e) {
            e.printStackTrace();
        }
    }

    /**
     * 权限申请
     */
    private void checkPermission() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            String[] permissions = new String[]{
                    Manifest.permission.RECORD_AUDIO,
                    Manifest.permission.WRITE_EXTERNAL_STORAGE,
                    Manifest.permission.ACCESS_FINE_LOCATION,
                    Manifest.permission.ACCESS_COARSE_LOCATION
            };
            for (String permission : permissions) {
                if (ContextCompat.checkSelfPermission(this, permission) != PackageManager.PERMISSION_GRANTED) {
                    ActivityCompat.requestPermissions(this, permissions, 200);
                    return;
                }
            }
        }
    }


    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[]
            grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && requestCode == 200) {
            for (int i = 0; i < permissions.length; i++) {
                if (grantResults[i] != PackageManager.PERMISSION_GRANTED) {
                    Intent intent = new Intent();
                    intent.setAction(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
                    Uri uri = Uri.fromParts("package", getPackageName(), null);
                    intent.setData(uri);
                    startActivityForResult(intent, 200);
                    return;
                }
            }
        }
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (resultCode == RESULT_OK && requestCode == 200) {
            checkPermission();
        }
    }

    @Override
    protected void onPause() {
        super.onPause();
        MediaManager.pause();
    }

    @Override
    protected void onResume() {
        super.onResume();
        MediaManager.resume();
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        MediaManager.release();
    }


}